Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DICOMSeriesToVolumeOperator Slice Removal Fix #527

Merged

Conversation

bluna301
Copy link
Contributor

@bluna301 bluna301 commented Feb 14, 2025

I discovered that the DICOMSeriesToVolumeOperator does not correctly handle slice removal within the prepare_series method.

I tested with an axial MRI series that has a single, non-image DICOM file (ImageOrientationPatient and ImagePositionPatient tags are absent). This method is built to handle cases like this and remove the slice prior to volume conversion; however, I discovered the removal process is incorrect. Below is a terminal output when testing the current operator (I added in a few logs for debugging):

WARNING:root:No selection rules given; select all series.
Slice index to remove:  40
Total slices before removal: 63
Removed slice index:  0
Total slices after removal: 62
Traceback (most recent call last):
  File "/home/bluna301/monai-deploy-app-sdk/monai/deploy/operators/dicom_series_to_volume_operator.py", line 442, in <module>
    test()
  File "/home/bluna301/monai-deploy-app-sdk/monai/deploy/operators/dicom_series_to_volume_operator.py", line 434, in test
    image = vol_op.convert_to_image(study_selected_series_list)
  File "/home/bluna301/monai-deploy-app-sdk/monai/deploy/operators/dicom_series_to_volume_operator.py", line 75, in convert_to_image
    self.prepare_series(dicom_series)
  File "/home/bluna301/monai-deploy-app-sdk/monai/deploy/operators/dicom_series_to_volume_operator.py", line 250, in prepare_series
    series._sop_instances = sorted(series._sop_instances, key=lambda s: s.distance)
  File "/home/bluna301/monai-deploy-app-sdk/monai/deploy/operators/dicom_series_to_volume_operator.py", line 250, in <lambda>
    series._sop_instances = sorted(series._sop_instances, key=lambda s: s.distance)
AttributeError: 'DICOMSOPInstance' object has no attribute 'distance'

Slice removal is occurring (total # of slices drops by 1), but the wrong slice is being removed; thus, the non-image DICOM file is still present and causes the error. The current removal functionality (below) iterates over indices of slice_indices_to_be_removed, not the actual slice indices stored in the list (i.e. the actual slice indices of series._sop_instances). This explains why slice 0 is being removed (1 element in list = 0th index).

for sl_index, _ in enumerate(slice_indices_to_be_removed):
     del series._sop_instances[sl_index]

My fix is to iterate over a sorted slice_indices_to_be_removed in reverse order and pull out the slice index to delete; sorting in reverse order will allow us to remove slices without having to worry about reindexing. Below is the terminal output with the fixes implemented (slice index to remove = removed slice index):

WARNING:root:No selection rules given; select all series.
Slice index to remove:  40
Total slices before removal: 63
Removed slice index:  40
Total slices after removal: 62
The (0028,0101) 'Bits Stored' value (12-bit) doesn't match the JPEG 2000 data (9-bit). It's recommended that you change the 'Bits Stored' value
The (0028,0101) 'Bits Stored' value (12-bit) doesn't match the JPEG 2000 data (10-bit). It's recommended that you change the 'Bits Stored' value
Image NumPy array shape (index order DHW): (62, 432, 432)
SeriesInstanceUID: 1.2.276.0.7230010.3.1.3.1701077560.1.1739564024.131542
Modality: MR
SeriesDescription: Ax T2 FS MVXD RTr 0gap
PatientPosition: FFS
SeriesNumber: 301
row_pixel_spacing: 0.78703701496124
col_pixel_spacing: 0.78703701496124
depth_pixel_spacing: 5.0
row_direction_cosine: [1.0, 0.0, 0.0]
col_direction_cosine: [0.0, 1.0, 0.0]
depth_direction_cosine: [0.0, 0.0, 1.0]
dicom_affine_transform: [[   0.78703701    0.            0.         -172.00736088]
 [   0.            0.78703701    0.         -178.60647672]
 [   0.            0.            5.         -158.39006042]
 [   0.            0.            0.            1.        ]]
nifti_affine_transform: [[  -0.78703701   -0.           -0.          172.00736088]
 [  -0.           -0.78703701   -0.          178.60647672]
 [   0.            0.            5.         -158.39006042]
 [   0.            0.            0.            1.        ]]
StudyInstanceUID: 1.2.276.0.7230010.3.1.2.1701077560.1.1739564024.131541
StudyID: 
StudyDate: 
StudyTime: 
StudyDescription: MRI LIVER ELASTOGRAPHY-ONLY
AccessionNumber: 

I think we should make the slice removal confirmation an info log so that users have some feedback that this removal occurred. Take it or leave it on the debug logs (would be fine removing the total slice # logs all together), will defer to your guidance here.

Signed-off-by: bluna301 <luna.bryanr@gmail.com>
@bluna301 bluna301 changed the title DICOMSeriesToVolumeOperator Slice Removal Fix [WIP] DICOMSeriesToVolumeOperator Slice Removal Fix Feb 14, 2025
@bluna301 bluna301 changed the title [WIP] DICOMSeriesToVolumeOperator Slice Removal Fix DICOMSeriesToVolumeOperator Slice Removal Fix Feb 14, 2025
@bluna301 bluna301 requested a review from MMelQin February 14, 2025 21:32
Copy link
Collaborator

@MMelQin MMelQin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me and thanks for fixing this bug.

@MMelQin MMelQin merged commit e7420e0 into Project-MONAI:main Feb 25, 2025
5 of 6 checks passed
@bluna301
Copy link
Contributor Author

Thanks Ming!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants